home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / winlib.lzh / WINLIB / POPUP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-03  |  13.8 KB  |  444 lines

  1. /********************************************************************
  2.  *                                                                    *
  3.  *    Popup menu bars for inside dialog boxes and dropside menus        *
  4.  *                                                                    *
  5.  *    Copyright (C) 1993 - 1994, Bitgate Software and Clever Bits.    *
  6.  *    All Rights Reserved.                                            *
  7.  *                                                                    *
  8.  *    Routines to handle dropdown menus (like Windows), popup menus    *
  9.  *    with previously selected object alignment, side menu bars for    *
  10.  *    popups, dropdowns, and desktop menu routines.                    *
  11.  *                                                                    *
  12.  ********************************************************************
  13.  *                                                                    *
  14.  *    Update log:                                                        *
  15.  *                                                                    *
  16.  *    [1.6.93 - 19.2.94] Ken Hollis                                    *
  17.  *                        - designed routines                            *
  18.  *        PDoPopup        - fixed serious bug in AES buffer grab        *
  19.  *                        - fixed drawing of objects for 3D type        *
  20.  *                        - fixed DISABLED bug and optimized stuff    *
  21.  *                        - added growth animation option                *
  22.  *        PDoPopupAddr    - added for OBJECTs already found            *
  23.  *                        - took out memory allocations (problems!)    *
  24.  *        PPopup_DialXY    - fixed repositioning problem                *
  25.  *                        - touched up routines                        *
  26.  *        PPopup_WinXY    - fixed repositioning problem                *
  27.  *                        - majorly modified and optimized            *
  28.  *                        - touched up routines                        *
  29.  *                                                                    *
  30.  *    To be added:                                                    *
  31.  *    """"""""""""                                                    *
  32.  *    Keyboard movable selection bar                                    *
  33.  *    Up and down arrows for additional choices (choices via an array)*
  34.  *    Popup menus act same as regular menu bars (ie. attach/detach)    *
  35.  *    Popup menus can be windowed as well                                *
  36.  *                                                                    *
  37.  ********************************************************************/
  38.  
  39. #include <vdi.h>        /* Standard VDI bindings */
  40. #include <tos.h>        /* Standard TOS bindings */
  41.  
  42. #include <stdio.h>        /* Standard IO bindings */
  43.  
  44. #include "winlib.h"        /* WinLIB header file */
  45. #include "nkcc.h"        /* Normalized Keycodes header file */
  46.  
  47. void *dpbuffer, *dialbuffer, *winbuffer;
  48. int PopupVDIhandle;
  49. MFDB srcp,destp;
  50. long bufferp, buflenp;
  51.  
  52. #ifndef __POPUP__
  53. #define __POPUP__
  54. #endif
  55.  
  56. GLOBAL void PPopup_DialXY(OBJECT *srctree, int srcindex, OBJECT *desttree)
  57. {
  58.     int    tx, ty;
  59.     int ox, oy;
  60.  
  61.     desttree->ob_x = srctree->ob_x;
  62.     desttree->ob_y = srctree->ob_y;
  63.  
  64.     objc_offset(srctree, srcindex, &ox, &oy);
  65.  
  66.     desttree->ob_x += ox;
  67.     desttree->ob_y += oy;
  68.  
  69.     desttree->ob_x--;
  70.     desttree->ob_y--;
  71.  
  72.     if ((tx = (desttree->ob_x + desttree->ob_width) - (desk.g_x + desk.g_w)) < 0)
  73.         tx = 0;
  74.     else
  75.         tx += 8;
  76.  
  77.     if (((desttree->ob_y + desttree->ob_height) - (desk.g_y + desk.g_h)) < 0)
  78.         ty = 0;
  79.     else
  80.         ty -= desttree->ob_y + desttree->ob_height;
  81.  
  82.     desttree->ob_x -= tx;
  83.     desttree->ob_y += ty;
  84. }
  85.  
  86. GLOBAL void PDropdown_DialXY(OBJECT *srctree, int srcindex, OBJECT *desttree)
  87. {
  88.     int    tx, ty;
  89.     int ox, oy;
  90.  
  91.     desttree->ob_x = srctree->ob_x;
  92.     desttree->ob_y = srctree->ob_y + srctree->ob_height;
  93.  
  94.     objc_offset(srctree, srcindex, &ox, &oy);
  95.  
  96.     desttree->ob_x += ox;
  97.     desttree->ob_y += oy;
  98.  
  99.     desttree->ob_x--;
  100.     desttree->ob_y -= 2;
  101.  
  102.     if ((tx = (desttree->ob_x + desttree->ob_width) - (desk.g_x + desk.g_w)) < 0)
  103.         tx = 0;
  104.     else
  105.         tx += 8;
  106.  
  107.     if (((desttree->ob_y + desttree->ob_height) - (desk.g_y + desk.g_h)) < 0)
  108.         ty = 0;
  109.     else
  110.         ty -= desttree->ob_y + desttree->ob_height;
  111.  
  112.     desttree->ob_x -= tx;
  113.     desttree->ob_y += ty;
  114. }
  115.  
  116. GLOBAL void PPopup_WinXY(WINDOW *win, int srcindex, OBJECT *desttree)
  117. {
  118.     int    tx, ty;
  119.     GRECT work;
  120.  
  121.     WWindGet(win, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w, &work.g_h);
  122.  
  123.     desttree->ob_x = win->tree[srcindex].ob_x + work.g_x;
  124.     desttree->ob_y = win->tree[srcindex].ob_y + work.g_y;
  125.  
  126.     desttree->ob_x--;
  127.     desttree->ob_y--;
  128.  
  129.     if ((tx = (desttree->ob_x + desttree->ob_width) - (desk.g_x + desk.g_w)) < 0)
  130.         tx = 0;
  131.  
  132.     if ((ty = (desttree->ob_y + desttree->ob_height) - (desk.g_y + desk.g_h)) < 0)
  133.         ty = 0;
  134.  
  135.     desttree->ob_x -= tx;
  136.     desttree->ob_y -= ty;
  137. }
  138.  
  139. GLOBAL void PDropdown_WinXY(WINDOW *win, int srcindex, OBJECT *desttree)
  140. {
  141.     int    tx, ty;
  142.     GRECT work;
  143.  
  144.     WWindGet(win, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w, &work.g_h);
  145.  
  146.     desttree->ob_x = win->tree[srcindex].ob_x + work.g_x;
  147.     desttree->ob_y = (win->tree[srcindex].ob_y + win->tree[srcindex].ob_height) + work.g_y;
  148.  
  149.     desttree->ob_x--;
  150.     desttree->ob_y -= 2;
  151.  
  152.     if ((tx = (desttree->ob_x + desttree->ob_width) - (desk.g_x + desk.g_w)) < 0)
  153.         tx = 0;
  154.  
  155.     if ((ty = (desttree->ob_y + desttree->ob_height) - (desk.g_y + desk.g_h)) < 0)
  156.         ty = 0;
  157.  
  158.     desttree->ob_x -= tx;
  159.     desttree->ob_y -= ty;
  160. }
  161.  
  162. GLOBAL void PMovePopupCoord(OBJECT *desttree, int x, int y)
  163. {
  164.     int    tx, ty;
  165.  
  166.     desttree->ob_x = x;
  167.     desttree->ob_y = y;
  168.  
  169.     desttree->ob_x--;
  170.     desttree->ob_y--;
  171.  
  172.     if ((tx = (desttree->ob_x + desttree->ob_width) - (desk.g_x + desk.g_w)) < 0)
  173.         tx = 0;
  174.  
  175.     if ((ty = (desttree->ob_y + desttree->ob_height) - (desk.g_y + desk.g_h)) < 0)
  176.         ty = 0;
  177.  
  178.     desttree->ob_x -= tx;
  179.     desttree->ob_y -= ty;
  180. }
  181.  
  182. GLOBAL void PMovePopup(OBJECT *dial, int oldpos, int newpos)
  183. {
  184.     OBJECT    *ob,*obnewpos;
  185.     int    obx,oby,obnx,obny;
  186.  
  187.     ob = &dial[ROOT];
  188.     rsrc_gaddr(R_TREE, oldpos, &ob);
  189.     obnewpos = &dial[newpos];
  190.     rsrc_gaddr(R_OBJECT, newpos, &obnewpos);
  191.     objc_offset(ob, oldpos, &obx, &oby);
  192.  
  193.     obnx = (obnewpos->ob_x) - obx;
  194.     obny = (obnewpos->ob_y) - (oby - 1);
  195.     ob->ob_x = obnx;
  196.     ob->ob_y = obny;
  197.  
  198.     if (ob->ob_x + ob->ob_width > desk.g_x + desk.g_w)
  199.         ob->ob_x = desk.g_x + desk.g_w - ob->ob_width;
  200.     if (ob->ob_y + ob->ob_height > desk.g_y + desk.g_h)
  201.         ob->ob_y = desk.g_y + desk.g_h - ob->ob_height;
  202. }
  203.  
  204. /*
  205.  *    Move popup box relative to window
  206.  *
  207.  *    win     : Window structure
  208.  *    pindex  : Popup index number
  209.  *    desttree: Destination tree (popup address)
  210.  */
  211. GLOBAL void PMovePopup_WinXY(WINDOW *win, int pindex, OBJECT *desttree)
  212. {
  213.     int    tx, ty;
  214.     int ox, oy;
  215.     GRECT work;
  216.  
  217.     if (win->popups[pindex]<=0) return;
  218.  
  219.     WWindGet(win, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w, &work.g_h);
  220.  
  221.     objc_offset(desttree, win->popups[pindex], &ox, &oy);
  222.  
  223.     desttree->ob_x = desttree->ob_x;
  224.     desttree->ob_y = (desttree->ob_y - oy) + work.g_y;
  225.  
  226.     if (win->menubar!=NULL)
  227.         desttree->ob_y += 17;
  228.  
  229.     if ((tx = (desttree->ob_x + desttree->ob_width) - (desk.g_x + desk.g_w)) < 0)
  230.         tx = 0;
  231.  
  232.     if ((ty = (desttree->ob_y + desttree->ob_height) - (desk.g_y + desk.g_h)) < 0)
  233.         ty = 0;
  234.  
  235.     desttree->ob_x -= tx;
  236.     desttree->ob_y -= ty;
  237. }
  238.  
  239. GLOBAL int PDoPopup(WINDOW *win, int index, OBJECT *menu_addr, int show, int x, int y, int w, int h)
  240. {
  241.     int LastOb,CurrOb,work_out[57];
  242.     int button,mx,my;
  243.     void *ourbuffer;
  244.     OBJECT *ptr;
  245.     GRECT work;
  246.  
  247.     WWindGet(win, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w, &work.g_h);
  248.  
  249.     vq_extnd(VDIhandle, 1, work_out);
  250.  
  251.     rsrc_gaddr(R_TREE, index, &ptr);
  252.  
  253.     ourbuffer = scrsave(VDIhandle, ptr->ob_x, ptr->ob_y, ptr->ob_width, ptr->ob_height);
  254.  
  255.     if (x!=0 && y!=0 && w!=0 && h!=0)
  256.         graf_growbox(x + work.g_x, y + work.g_y, w, h, ptr->ob_x, ptr->ob_y, ptr->ob_width, ptr->ob_height);
  257.  
  258.     objc_draw(ptr, 0, 6, ptr->ob_x, ptr->ob_y, ptr->ob_width, ptr->ob_height);
  259.     LastOb = -1;
  260.  
  261.     do {
  262.         vq_mouse(VDIhandle,&button,&mx,&my);
  263.         CurrOb = objc_find(ptr, 0, MAX_DEPTH, mx, my);
  264.         if ((CurrOb==-1) && (ptr[LastOb].ob_flags & SELECTABLE) && !(ptr[LastOb].ob_state & DISABLED)) {
  265.             objc_change(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  266.             objc_draw(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  267.             LastOb = -1;
  268.         }
  269.         if ((CurrOb>0) && (LastOb!=CurrOb) && (ptr[LastOb].ob_flags & SELECTABLE) && !(ptr[LastOb].ob_state & DISABLED)) {
  270.             if ((LastOb>0) && !(ptr[LastOb].ob_state & DISABLED)) {
  271.                 objc_change(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  272.                 objc_draw(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  273.             }
  274.             LastOb = -1;
  275.         }
  276.         if ((CurrOb!=LastOb) && (ptr[CurrOb].ob_flags & SELECTABLE) && !(ptr[CurrOb].ob_state & DISABLED)) {
  277.             if ((LastOb>0) && !(ptr[LastOb].ob_state & DISABLED)) {
  278.                 objc_change(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  279.                 objc_draw(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  280.             }
  281.             if ((CurrOb>0) && !(ptr[CurrOb].ob_state & DISABLED)) {
  282.                 objc_change(ptr,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,SELECTED,1);
  283.                 objc_draw(ptr,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  284.             }
  285.             LastOb = CurrOb;
  286.         }
  287.     } while(button!=1);
  288.  
  289.     if ((LastOb>0) && !(ptr[LastOb].ob_state & DISABLED) && (ptr[LastOb].ob_flags & SELECTABLE)) {
  290.         objc_change(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  291.         objc_draw(ptr,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  292.     }
  293.     if ((CurrOb>0) && !(ptr[CurrOb].ob_state & DISABLED) && (ptr[CurrOb].ob_flags & SELECTABLE)) {
  294.         objc_change(ptr,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  295.         objc_draw(ptr,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  296.     }
  297.  
  298.     scrrestore(ourbuffer);
  299.  
  300.     if (x!=0 && y!=0 && w!=0 && h!=0)
  301.         graf_shrinkbox(x + work.g_x, y + work.g_y, w, h, ptr->ob_x, ptr->ob_y, ptr->ob_width, ptr->ob_height);
  302.  
  303.     return(LastOb);
  304. }
  305.  
  306. GLOBAL int PDoPopupAddr(OBJECT *index)
  307. {
  308.     int LastOb,CurrOb,work_out[57];
  309.     int button,mx,my;
  310.     void *ourbuffer;
  311.  
  312.     vq_extnd(VDIhandle, 1, work_out);
  313.  
  314.     ourbuffer = scrsave(VDIhandle, index->ob_x, index->ob_y, index->ob_width, index->ob_height);
  315.     objc_draw(index, 0, 6, index->ob_x, index->ob_y, index->ob_width, index->ob_height);
  316.     LastOb = -1;
  317.  
  318.     do {
  319.         vq_mouse(VDIhandle,&button,&mx,&my);
  320.         CurrOb = objc_find(index, 0, MAX_DEPTH, mx, my);
  321.         if ((CurrOb==-1) && (LastOb!=-1) && (index[LastOb].ob_flags & SELECTABLE) && !(index[LastOb].ob_state & DISABLED)) {
  322.             objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  323.             LastOb = -1;
  324.         }
  325.         if ((CurrOb>0) && (LastOb!=CurrOb) && (index[LastOb].ob_flags & SELECTABLE) && !(index[LastOb].ob_state & DISABLED)) {
  326.             if ((LastOb>0) && !(index[LastOb].ob_state & DISABLED)) {
  327.                 objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  328.             }
  329.             LastOb = -1;
  330.         }
  331.         if ((CurrOb!=LastOb) && (index[CurrOb].ob_flags & SELECTABLE) && !(index[CurrOb].ob_state & DISABLED)) {
  332.             if ((LastOb>0) && !(index[LastOb].ob_state & DISABLED)) {
  333.                 objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  334.             }
  335.             if ((CurrOb>0) && !(index[CurrOb].ob_state & DISABLED)) {
  336.                 objc_change(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,SELECTED,1);
  337.             }
  338.             LastOb = CurrOb;
  339.         }
  340.     } while(button!=1);
  341.  
  342.     if ((LastOb>0) && !(index[LastOb].ob_state & DISABLED) && (index[LastOb].ob_flags & SELECTABLE)) {
  343.         objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  344.         objc_draw(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  345.     }
  346.     if ((CurrOb>0) && !(index[CurrOb].ob_state & DISABLED) && (index[CurrOb].ob_flags & SELECTABLE)) {
  347.         objc_change(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  348.         objc_draw(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  349.     }
  350.  
  351.     scrrestore(ourbuffer);
  352.  
  353.     return(LastOb);
  354. }
  355.  
  356. GLOBAL int POpenPopupWorkspace(void)
  357. {
  358.     int WorkOut[64];
  359.     int WorkIn[]={1,1,1,1,1,1,1,1,1,1,2};
  360.     int j;
  361.  
  362.     PopupVDIhandle=graf_handle(&j,&j,&j,&j);
  363.     v_opnvwk(WorkIn,&PopupVDIhandle,WorkOut);
  364.  
  365.     return(TRUE);
  366. }
  367.  
  368. GLOBAL int PShowPopupDesk(OBJECT *index)
  369. {
  370.     dpbuffer = scrsave(VDIhandle, index->ob_x, index->ob_y, index->ob_width, index->ob_height);
  371.     if (dpbuffer) {
  372.         objc_draw(index, 0, 6, index->ob_x, index->ob_y, index->ob_width, index->ob_height);
  373.         return TRUE;
  374.     } else
  375.         return FALSE;
  376. }
  377.  
  378. GLOBAL int PEndPopupDesk(OBJECT *index)
  379. {
  380.     if (dpbuffer) {
  381.         scrrestore(dpbuffer);
  382.         return TRUE;
  383.     } else {
  384.         form_dial(3, index->ob_x, index->ob_y, index->ob_width, index->ob_height,
  385.                      index->ob_x, index->ob_y, index->ob_width, index->ob_height);
  386.         return FALSE;
  387.     }
  388. }
  389.  
  390. GLOBAL int PDoPopupDeskMenu(OBJECT *index, int *retbtn)
  391. {
  392.     int LastOb,CurrOb;
  393.     int button,mx,my;
  394.  
  395.     *retbtn = 0;
  396.     LastOb = -1;
  397.  
  398.     do {
  399.         vq_mouse(VDIhandle,&button,&mx,&my);
  400.         CurrOb = objc_find(index, 0, MAX_DEPTH, mx, my);
  401.  
  402.         if (CurrOb==-1) {
  403.             if ((LastOb>0) && !(index[LastOb].ob_state & DISABLED) && (index[LastOb].ob_flags & SELECTABLE)) {
  404.                 objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  405.                 objc_draw(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  406.             }
  407.             if ((CurrOb>0) && !(index[CurrOb].ob_state & DISABLED) && (index[CurrOb].ob_flags & SELECTABLE)) {
  408.                 objc_change(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  409.                 objc_draw(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  410.             }
  411.  
  412.             *retbtn = FALSE;
  413.             return 0;
  414.         }
  415.         
  416.         if ((CurrOb==-1) && (index[LastOb].ob_flags & SELECTABLE) && !(index[LastOb].ob_state & DISABLED)) {
  417.             objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  418.             LastOb = -1;
  419.         }
  420.         if ((CurrOb>0) && (LastOb!=CurrOb) && (index[LastOb].ob_flags & SELECTABLE) && !(index[LastOb].ob_state & DISABLED)) {
  421.             if ((LastOb>0) && !(index[LastOb].ob_state & DISABLED)) {
  422.                 objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  423.             }
  424.             LastOb = -1;
  425.         }
  426.         if ((CurrOb!=LastOb) && (index[CurrOb].ob_flags & SELECTABLE) && !(index[CurrOb].ob_state & DISABLED)) {
  427.             if ((LastOb>0) && !(index[LastOb].ob_state & DISABLED)) {
  428.                 objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  429.             }
  430.             if ((CurrOb>0) && !(index[CurrOb].ob_state & DISABLED)) {
  431.                 objc_change(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,SELECTED,1);
  432.             }
  433.             LastOb = CurrOb;
  434.         }
  435.     } while(button!=1);
  436.  
  437.     if ((LastOb>0) && !(index[LastOb].ob_state & DISABLED) && (index[LastOb].ob_flags & SELECTABLE)) {
  438.         objc_change(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  439.         objc_draw(index,LastOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  440.     }
  441.     if ((CurrOb>0) && !(index[CurrOb].ob_state & DISABLED) && (index[CurrOb].ob_flags & SELECTABLE)) {
  442.         objc_change(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,NORMAL,1);
  443.         objc_draw(index,CurrOb,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  444.     }
  445.  
  446.     *retbtn = TRUE;
  447.     return(LastOb);
  448. }